package com.estar.integaration.DS;

import java.io.Serializable;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.NoSuchElementException;

/**
 * Author: YJL
 * Date: 2021/12/29 11:29
 **/
public class Vertex implements VertexInterface, Serializable {

  private String data;//数据，标识此点
  private List<Edge> edgeList;//到该邻接点的边
  private boolean visited;//是否访问
  private VertexInterface previousVertex;//前驱节点

  public Vertex(String data){
    this.data = data;
    edgeList = new LinkedList<>();//每个顶点都有一个edgeList用来存储所有与该顶点有关系的边
    visited = false;
    previousVertex = null;
  }


  protected class Edge implements Serializable{
    private VertexInterface endVertex;//终点
    protected Edge(VertexInterface endVertex){
      this.endVertex = endVertex;
    }

    public VertexInterface getEndVertex() {
      return endVertex;
    }
  }

  private class NeighborIterator implements Iterator<VertexInterface>{

    Iterator<Edge> edgesIterator;

    private NeighborIterator(){
      edgesIterator = edgeList.iterator();//获取edgeList的Iterator
    }

    @Override
    public boolean hasNext() {
      return edgesIterator.hasNext();
    }

    @Override
    public VertexInterface next() {
      VertexInterface nextNeibor = null;
      if(edgesIterator.hasNext()){
        Edge edgeToNextNeighbor = edgesIterator.next();//LinkedList里面存储的是Edge
        nextNeibor = edgeToNextNeighbor.getEndVertex();//从边中取出下一个点
      }else {
        throw new NoSuchElementException();
      }
      return nextNeibor;
    }

    @Override
    public void remove(){
      throw new UnsupportedOperationException();//不允许移除
    }
  }



  @Override
  public String getData() {
    return data;
  }

  @Override
  public void visit() {
      this.visited = true;
  }

  @Override
  public void unVisit() {
      this.visited = false;
  }

  @Override
  public boolean isVisited() {
    return visited;
  }

  @Override
  public boolean connect(VertexInterface endVertex, double edgeWeight) {
    //把边插入顶点的邻接表
    boolean result = false;
    if(!this.equals(endVertex)){//不是本点自己
      Iterator<VertexInterface> neibors = this.getNeighborIterator();
      boolean duplicateEdge = false;//重复边
      while (!duplicateEdge && neibors.hasNext()){//保证不添加重复边
        VertexInterface nextNeighbor = neibors.next();
        if(endVertex.equals(nextNeighbor)){//出现重复
          duplicateEdge = true;
          break;
        }
      }
      if(!duplicateEdge){
        edgeList.add(new Edge(endVertex));//添加一条新的边
        result = true;
      }
    }
    return result;
  }

  @Override
  public boolean connect(VertexInterface endVertex) {
    return connect(endVertex,0);
  }

  @Override
  public Iterator<VertexInterface> getNeighborIterator() {
    return new NeighborIterator();
  }

  @Override
  public boolean hasNeighbor() {
    return !(edgeList.isEmpty());
  }

  //获得该顶点第一个未被访问的邻接点
  @Override
  public VertexInterface getUnvisitedNeighbor() {
    VertexInterface result = null;
    Iterator<VertexInterface> neighbors = getNeighborIterator();
    while (neighbors.hasNext() && result == null){
      VertexInterface nextNeighbor = neighbors.next();
      if(!nextNeighbor.isVisited()){
        result = nextNeighbor;
      }
    }
    return result;
  }

  @Override
  public void setPredecessor(VertexInterface predecessor) {
    this.previousVertex = predecessor;
  }

  @Override
  public VertexInterface getPredecessor() {
    return this.previousVertex;
  }

  public boolean equals(Object other){
    boolean result;
    if(other == null ||(getClass() != other.getClass())){
      return false;
    }else {
      Vertex otherVertex = (Vertex)other;
      result  = data.equals(otherVertex.data);
    }
    return result;
  }

}

